package net.wangds.yunz.auth.comp;

import net.wangds.auth.account.repo.rdbms.AccountUserRefJpaRepo;
import net.wangds.auth.module.Account;
import net.wangds.auth.module.User;
import net.wangds.auth.module.UserStatusEnum;
import net.wangds.auth.user.comp.GeneralUserComp;
import net.wangds.data.DisableEnum;
import net.wangds.data.RemovedEnum;
import net.wangds.jdbc.comp.jdbc.JdbcComp;
import net.wangds.jpa.comp.AbstractRemovedComp;
import net.wangds.log.helper.LogHelper;
import net.wangds.program.auth.module.AuthAccount;
import net.wangds.program.auth.repo.rdbms.AuthAccountJpaRepo;
import net.wangds.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@SuppressWarnings("unused")
@Component
@Primary
public class AuthAccountComp extends AbstractRemovedComp<AuthAccount> {

    private final AuthAccountJpaRepo mmRepoAccount;

    private final AccountUserRefJpaRepo mmRepoRefUser;

    private final GeneralUserComp mmCmpUser;

    @Autowired
    private JdbcComp mmCmpJdbc;

    @Autowired
    protected AuthAccountComp(
            AuthAccountJpaRepo repo
            , AccountUserRefJpaRepo refUsrRepo
            , GeneralUserComp userCmp
    ) {
        super(repo);
        this.mmRepoAccount = repo;
        this.mmRepoRefUser = refUsrRepo;
        this.mmCmpUser = userCmp;
    }

    public List<User> listAccountUsers(Account acc){
        return mmRepoRefUser.findAllByAccountIdAndDisableAndRemoved(acc.getId(),
                DisableEnum.NORMAL,
                RemovedEnum.NORMAL)
                .stream().map(c->
                        mmCmpUser.findById(c.getUserId()).orElseGet(null)).collect(Collectors.toList());
    }

    public Optional<AuthAccount> findNormalUserByLoginName(String loginname){
        //LogHelper.dev(()->"findNormalUserByLoginName，"+loginname);
        return mmRepoAccount.findByLoginnameAndStatusAndRemoved(loginname, UserStatusEnum.NORMAL, RemovedEnum.NORMAL);
    }


    public Page<User> listAccountUnbindUsers(AuthAccount acc, PageRequest pr) {
        List<String> exceptUids = listAccountUsers(acc).stream().map(u -> u.getId()).collect(Collectors.toList());

        LogHelper.info(JsonUtils.toJsonStr(exceptUids));
        LogHelper.info(JsonUtils.toJsonStr(pr));

        return mmCmpUser.selectUsersExcept(exceptUids,
                RemovedEnum.NORMAL, pr);

    }

    public boolean existsByLoginname(String loginname) {
        return this.mmRepoAccount.existsByLoginname(loginname);
    }

    public Page<AuthAccount> findFamous(String keywords, Pageable pg) {
        keywords = StringUtils.trim(keywords);

        if(StringUtils.isBlank(keywords)){
            return mmRepoAccount.findAll(pg);
        }else {
            return mmCmpJdbc.executeQuery("SELECT t1.id, t1.removed, t1.ctm, t1.avatar, loginname, nickname, '******' as password, \n" +
                    "t1.status, wx_open_id, wx_union_id, business_account, cata, community_account,\n" +
                    "description, device_id, referee, score, tel, icon_id, shop_id, shop_status\n" +
                    " FROM aa_m10_account_art t1 where (t1.tel regexp ? or t1.nickname regexp ?) and t1.removed = 0",
                    new Object[]{keywords, keywords}, pg, AuthAccount.class);
        }
    }

    @Override
    public Page<AuthAccount> findByKeywords(String keywords, Pageable paging) {
        if(StringUtils.isBlank(keywords)){
            return this.findAll(paging);
        }

        return mmCmpJdbc.executeQuery("SELECT t1.id, t1.removed, t1.ctm, t1.avatar, t1.display_name, t1.loginname, t1.nickname, '' as `password`,\n" +
                        "t1.status, t1.wx_open_id, t1.wx_union_id, t1.`description`, t1.device_id, t1.icon_id, t1.order_weight, t1.referee,\n" +
                        "t1.score, t1.tel FROM pro_auth_account t1\n" +
                        "where (t1.loginname regexp ? or t1.tel regexp ? or t1.nickname regexp ? or t1.display_name regexp ?) and t1.removed = 0",
                new Object[]{keywords, keywords, keywords, keywords}, paging, AuthAccount.class);
    }
}
